
#ifndef ELEMENTOEXTERNO_H_
#define ELEMENTOEXTERNO_H_
#include "ElementoCircuital.h"
#include "../Comunicaciones/Cliente.h"
#include <vector>

class ElementoExterno: public ElementoCircuital {
	class SalidaElementoExterno{
	public:
		~SalidaElementoExterno(){
			std::list<Conexion*>::iterator lit(L_conexiones.begin());
			std::list<Conexion*>::const_iterator lend(L_conexiones.end());
			while(lit!=lend){
				((*lit)->get_receptor())->desconectar_entrada((*lit)->get_nro_entrada());
				delete *lit;
				lit++;
			}
			L_conexiones.clear();
		}
		std::list<Conexion*> L_conexiones;
	};
	int cant_conexiones_actuales;
	int vueltas;
	bool simulado;
	std::string entradas;
	std::string salidas;
	std::string nombre;
	std::list<Conexion*> L_entradas;
	std::list<SalidaElementoExterno*> L_salidas;
	int tiempo_de_transicion;
	std::string ip;
	int port;
	Cliente* cliente;

public:
	ElementoExterno(int x,int y,int id,std::string ip, int port, Cliente* cliente, int cant_entradas,int cant_salidas,
						std::string name);
	virtual ~ElementoExterno();

	bool ready();
	bool entrada_ocupada(int nro_entrada);
	bool calcular_salida(int nro_Salida,int& t_transicion);
	void desconectar_entrada(int nro);
	void set_entrada(Conexion* cable);
	int calcular_cant_conexiones();

	/*
	 * Recalcula la dimension del elemento externo luego de una rotacion
	 */
	void recalcular_dimension();

	void agregar_conexion(Conexion* nueva_conexion, int nro_salida);
	void liberar_conexiones();
	void liberar_entradas();
	void cortar_cable(int id_cable);

	/*
	 * Calcula el ancho y el alto del elemento externo segun el angulo
	 */
	void calcular_ancho(int *ancho, int *alto);

	std::string get_nombre(){return this->nombre;}
	void get_centro(int *x, int *y);

	/*
	 * Funciones que determinan la posicion donde repintar el elemento
	 */
	int get_pos_x_repaint();

	int get_pos_y_repaint();

	/*
	 * Funciones que segun la posicion x e y que se pase por parametro determina el nro de entrada o
	 * salida que se esta seleccionando
	 */
	int get_nro_entrada(int x, int y);

	int get_nro_salida(int x, int y);

	/*
	 * Funciones que devuelven las posiciones de entrada o salida que se les pasa por parametro
	 */
	int get_posicion_entrada_x (int nro);

	int get_posicion_entrada_y (int nro);

	int get_posicion_salida_x (int nro);

	int get_posicion_salida_y (int nro);


	int get_tiempo(){return this->tiempo_de_transicion;}
	int get_puerto(){return this->port;}
	std::string get_ip(){return this->ip;}
	int get_cant_entradas(){return this->L_entradas.size();}
	int get_cant_salidas(){return this->L_salidas.size();}

	Cliente* get_cliente(){
		return this->cliente;
	}

	std::list<Conexion*> get_lista_entradas(){return this->L_entradas;}
};

#endif /* ELEMENTOEXTERNO_H_ */
